package com.pactera.madp.cp.service.impl;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pactera.madp.common.data.tenant.TenantContextHolder;
import com.pactera.madp.cp.api.entity.CorpEntity;
import com.pactera.madp.cp.api.entity.wm.WorkMsgConfigEntity;
import com.pactera.madp.cp.api.entity.wm.WorkMsgEntity;
import com.pactera.madp.cp.api.entity.wm.WorkMsgTableMgtEntity;
import com.pactera.madp.cp.api.model.wm.CorpMsgTO;
import com.pactera.madp.cp.config.MsgStoreConfig;
import com.pactera.madp.cp.job.WorkMsgBackUpUtil;
import com.pactera.madp.cp.mapper.corp.CorpMapper;
import com.pactera.madp.cp.mapper.wm.WorkMsgMapper;
import com.pactera.madp.cp.service.IWorkMsgConfigService;
import com.pactera.madp.cp.service.IWorkMsgService;
import com.pactera.madp.cp.service.IWorkMsgTableMgtService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @author: yangpengwei
 * @time: 2020/11/25 5:03 下午
 * @description 会话内容存档业务实现
 */
@Slf4j
@Service
@AllArgsConstructor
public class WorkMsgServiceImpl extends ServiceImpl<WorkMsgMapper, WorkMsgEntity> implements IWorkMsgService {

    private final IWorkMsgConfigService msgConfigService;
    private final CorpMapper corpMapper;
    private final WorkMsgMapper workMsgMapper;
    private final IWorkMsgTableMgtService workMsgTableMgtService;
    private final MsgStoreConfig msgStoreConfig;

    /**
     * 对所有开启会话内容存档的企业进行数据同步
     */
    @Async
    @Override
    public void onAsyncMsg() {
        List<WorkMsgConfigEntity> list = msgConfigService.getAllAble();
        CorpMsgTO corpMsgTO;
        for (WorkMsgConfigEntity entity : list) {
            if(entity.getChatApplyStatus() == 4 && entity.getChatStatus() == 1) {
                //设置租户id
                TenantContextHolder.setTenantId(entity.getTenantId());

                int corpId = entity.getCorpId();
                String wxCorpId = getWxCorpId(corpId);
                if (wxCorpId.isEmpty()) {
                    return;
                }
                corpMsgTO = new CorpMsgTO();
                corpMsgTO.setCorpId(corpId);
                corpMsgTO.setWxCorpId(wxCorpId);
                corpMsgTO.setChatRsaKey(entity.getChatRsaKey());
                corpMsgTO.setChatSecret(entity.getChatSecret());
                log.info(entity.getCorpId()+"同步会话开始---------");
                doInsertMsg(corpMsgTO);
                log.info(entity.getCorpId()+"同步会话结束---------");
            }
        }
    }

    /**
     * 同步会话内容数据
     *
     * @param corpId 企业 id
     * @return 是否同步成功
     */
    @Override
    public boolean onAsyncMsg(int corpId) {
        WorkMsgConfigEntity entity = msgConfigService.getByCorpId(corpId);
        if (null != entity && entity.getChatApplyStatus() == 4 && entity.getChatStatus() == 1) {
            String wxCorpId = getWxCorpId(corpId);
            if (wxCorpId.isEmpty()) {
                return false;
            }
            CorpMsgTO corpMsgTO = new CorpMsgTO();
            corpMsgTO.setCorpId(corpId);
            corpMsgTO.setWxCorpId(wxCorpId);
            corpMsgTO.setChatRsaKey(entity.getChatRsaKey());
            corpMsgTO.setChatSecret(entity.getChatSecret());
            doInsertMsg(corpMsgTO);
            return true;
        }
        return false;
    }

    @Override
    public List<WorkMsgEntity> getWorkMessagesByMsgId(List<WorkMsgEntity> workMsgEntityList) {
        List<WorkMsgEntity> workMsgEntities = new ArrayList();
        QueryWrapper<WorkMsgEntity> workMsgEntityWrapper = new QueryWrapper();
        for (WorkMsgEntity workMsgEntity:
                workMsgEntityList) {
            workMsgEntityWrapper.eq("msg_id",workMsgEntity.getMsgId());
//            int corp = workMsgEntity.getCorpId() % 10;
//            workMsgEntities.add(baseMapper.selectByMsgId("cp_work_message_"+corp,workMsgEntity.getCorpId(),workMsgEntity.getMsgId()));
        }
        return workMsgEntities;
    }


    @Override
    public List<WorkMsgEntity> getWorkMessagesRangeByCorpIdWxRoomId(String corpId, String wxRoomId, Long id, int i,long startTime,long endTime) {
        if(i == 0){
            return this.baseMapper.getWorkMessagesRangeByCorpIdWxRoomIdByDesc(wxRoomId,corpId,id,startTime,endTime);
        }
        return this.baseMapper.getWorkMessagesRangeByCorpIdWxRoomIdByAsc(wxRoomId,corpId,id,startTime,endTime);
    }

    @Override
    public String getLatest(String wxExternalUserid, ArrayList<Object> list) {
        return this.baseMapper.getLatest(wxExternalUserid, list);
    }

    @Override
    public List<WorkMsgEntity> getWorkMessagesRangeByCorpId(String corpId, String from, String tolist, Long id, int i,long startTime,long endTime) {
        if(i == 0){
            return this.baseMapper.getWorkMessagesRangeByCorpIdByDesc(from,tolist,corpId,id,startTime,endTime);
        }
        return this.baseMapper.getWorkMessagesRangeByCorpIdByAsc(from,tolist,corpId,id,startTime,endTime);
    }

    @Override
    public List<WorkMsgEntity> isTouchqt(Integer corpId, String roomWxId, long compareUnix) {
        return this.baseMapper.isTouchqt(roomWxId, compareUnix);
    }

    @Override
    public Integer getMsgNum(long l) {
        return this.baseMapper.getMsgNum(l);
    }

    @Override
    public Integer isTouchOver(Integer corpId, List<Integer> msgIds, Long weekBegin) {
        return this.baseMapper.isTouchOver(msgIds, weekBegin);
    }

    @Override
    public List<WorkMsgEntity> page(String wxid, Integer type) {
        List<WorkMsgEntity> li = baseMapper.page(wxid, type);
        return li;
    }

    @Override
    public Integer contactEffective(Integer type, String wxUserId) {
        long startTime;
        long endTime;
        DateTime todayBegin = DateUtil.beginOfDay(DateUtil.date());
        DateTime todayEnd = DateUtil.endOfDay(DateUtil.date());
        if (type == 1) {
            startTime = DateUtil.offsetDay(todayBegin, -7).getTime();
            endTime = DateUtil.offsetDay(todayEnd, -1).getTime();
        } else if (type == 2) {
            startTime = DateUtil.offsetDay(todayBegin, -30).getTime();
            endTime = DateUtil.offsetDay(todayEnd, -1).getTime();
        } else {
            startTime = todayBegin.getTime();
            endTime = todayEnd.getTime();
        }
        return this.baseMapper.contactEffective(startTime, endTime, wxUserId);
    }

    /**
     * 获取最后一条信息的 seq
     *
     * @return seq
     */
    @Override
    public long findLastSeq(boolean fromCache) {
        WorkMsgTableMgtEntity we = workMsgTableMgtService.getSubTableByState(1);
        if (ObjectUtil.isNull(we)) {
            return 0;
        }
        if (fromCache) {
            Long lastSeq = we.getLastSeq();
            if (lastSeq < 1) {
                List<WorkMsgTableMgtEntity> list = workMsgTableMgtService.list(Wrappers.<WorkMsgTableMgtEntity>lambdaQuery()
                        .eq(WorkMsgTableMgtEntity::getState, 2)
                        .orderByDesc(WorkMsgTableMgtEntity::getId));
                if (list.isEmpty()) {
                    return 0;
                } else {
                    return list.get(0).getLastSeq();
                }
            }
            return we.getLastSeq();
        }
        // 更新序列号
        Long seq = workMsgMapper.findLastSeq(we.getMsgTableName());
        if (seq == null) {
            seq = we.getLastSeq();
        }
        return seq;
    }

    @Async
    @Override
    public boolean clearExpireMsg() {
        int storeDuration = msgStoreConfig.getStoreDuration();
        Integer offsetDay = 0 - storeDuration;
        long time = DateUtil.offsetDay(new Date(), offsetDay).getTime();
        return this.remove(Wrappers.<WorkMsgEntity>lambdaQuery().le(WorkMsgEntity::getMsgTime, time));
    }

    /**
     * 获取最后一条信息的 seq
     *
     * @param corpId 企业 id
     * @return seq
     */
    private int findLastSeq(long corpId) {
        Integer seq = baseMapper.selectLastSeq(corpId);
        if (null != seq) {
            return seq;
        }
        return 0;
    }

    private boolean doInsertMsg(CorpMsgTO entity) {
        try {
            boolean repeat = WorkMsgBackUpUtil.insertMsg(entity, findLastSeq(true));
            if (repeat) {
                doInsertMsg(entity);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    private String getWxCorpId(int corpId) {
        CorpEntity corpEntity = corpMapper.selectById(corpId);
        if (corpEntity == null) {
            return "";
        }
        return corpEntity.getWxCorpId();
    }

}
